using Firestarter.Test.Base;
using FireStarterModeller.BO;
using FireStarterModeller.Logic.Commands;
using FireStarterModeller.Test.BO;
using FireStarterModeller.UI.DetailsView;
using FireStarterModeller.UI.DetailsView.Controller;
using NUnit.Framework;
using Rhino.Mocks;

namespace FireStarterModeller.Test.UI.DetailsView.Controller
{
    [TestFixture]
    public class TestSolutionViewController
    {
        //TODO: 2009/02/16
        //Display solution with one assembly - done
        //Display solution with multiple assemblies - done
        //Display assembly - done
        //Display: Collape assembly view. - done
        //Select assembly - done
        //Create assembly - done
        //Create class (using current assembly) - done
        //Select class - done
        //Delete class - done
        //Delete assembly - done
        //Rename class - done
        //Rename assembly - done
        //Move class from one assembly to another
  

        [TestFixtureSetUp]
        public void SetupFixture()
        {
            TestUtilsDomain.SetupFixture();
        }
        [SetUp]
        public void SetupTest()
        {
            TestUtilsDomain.SetupTest();
        }

        
        //Select assembly
        [Test]
        public void Test_SelectAssembly()
        {
            //---------------Set up test pack-------------------
            SolutionViewModel model = new SolutionViewModel("MyProject");
            SolutionViewModel.AssemblyModel assembly1 = new SolutionViewModel.AssemblyModel("MyAsBsembly");
            model.Assemblies.Add(assembly1);
            SolutionViewModel.AssemblyModel assembly2 = new SolutionViewModel.AssemblyModel("MyAssembly2");
            model.Assemblies.Add(assembly2);
            SolutionViewController controller =
               new SolutionViewController(new CommandFactory(), new CommandRunner(), model);

            //---------------Assert PreConditions---------------   
            Assert.AreSame(assembly1, model.CurrentAssembly);

            //---------------Execute Test ----------------------
            controller.SelectAssembly(assembly2);
            //---------------Test Result -----------------------
            Assert.AreSame(assembly2, model.CurrentAssembly);

            //---------------Tear Down -------------------------          
        }

        //Create assembly
        [Test]
        public void Test_CreateAssembly()
        {
            //---------------Set up test pack-------------------
            DMSolution solution = TestUtilsShared.CreateSavedDMSolution();
            SolutionViewModel solutionViewModel = SolutionViewModel.BuildFrom(solution);
            const string assemblyName = "Assembly2";
            MockRepository mock = new MockRepository();
            ICommand command = MockRepository.GenerateStub<ICommand>();
            ICommandFactory commandFactory = MockRepository.GenerateStub<ICommandFactory>();
            ICommandRunner commandRunner = MockRepository.GenerateStub<ICommandRunner>();
            ISolutionViewController controller =
                new SolutionViewController(commandFactory, commandRunner, solutionViewModel);

            //--------------Set up expectations-----------------
            commandFactory.Expect(factory => factory.CreateCreateAssembly(solution, assemblyName)).Return(command);
            commandRunner.Expect(runner => runner.ApplyCommand(command));
            mock.ReplayAll();

            //---------------Execute Test ----------------------
            controller.CreateAssembly(assemblyName);

            //---------------Test Result -----------------------
            mock.VerifyAll();
            //---------------Tear Down -------------------------          
        }

        //Delete assembly
        [Test]
        public void Test_DeleteAssembly()
        {
            //---------------Set up test pack-------------------
            DMSolution solution = TestUtilsShared.CreateSavedDMSolution();

            SolutionViewModel solutionViewModel = SolutionViewModel.BuildFrom(solution);

            MockRepository mock = new MockRepository();
            ICommand command = MockRepository.GenerateStub<ICommand>();
            ICommandFactory commandFactory = MockRepository.GenerateStub<ICommandFactory>();
            ICommandRunner commandRunner = MockRepository.GenerateStub<ICommandRunner>();
            ISolutionViewController controller =
                new SolutionViewController(commandFactory, commandRunner, solutionViewModel);

            //--------------Set up expectations-----------------
            commandFactory.Expect(factory => factory.CreateDeleteAssembly(solution.DefaultAssembly)).Return(command);
            commandRunner.Expect(runner => runner.ApplyCommand(command));
            mock.ReplayAll();

            //---------------Execute Test ----------------------
            controller.DeleteAssembly(solutionViewModel.CurrentAssembly);

            //---------------Test Result -----------------------
            mock.VerifyAll();
            //---------------Tear Down -------------------------          
        }

        //Rename assembly
        [Test]
        public void Test_RenameAssembly()
        {
            //---------------Set up test pack-------------------
            DMSolution solution = TestUtilsShared.CreateSavedDMSolution();
            SolutionViewModel solutionViewModel = SolutionViewModel.BuildFrom(solution);
 
            MockRepository mock = new MockRepository();
            ICommand command = MockRepository.GenerateStub<ICommand>();
            ICommandFactory commandFactory = MockRepository.GenerateStub<ICommandFactory>();
            ICommandRunner commandRunner = MockRepository.GenerateStub<ICommandRunner>();
            ISolutionViewController controller =
                new SolutionViewController(commandFactory, commandRunner, solutionViewModel);
            const string newName = "NewName";

            //--------------Set up expectations-----------------
            commandFactory.Expect(factory => commandFactory.CreateRenameAssembly(solution.DefaultAssembly, newName)).Return(command);
            commandRunner.Expect(runner => runner.ApplyCommand(command));
            mock.ReplayAll();

            //---------------Execute Test ----------------------
            controller.RenameAssembly(solutionViewModel.CurrentAssembly, newName);

            //---------------Test Result -----------------------
            mock.VerifyAll();
            //---------------Tear Down -------------------------          
        }
        //Select class
        [Test]
        public void Test_SelectClass()
        {
            //---------------Set up test pack-------------------
            SolutionViewModel model = new SolutionViewModel("MyProject");
            SolutionViewModel.AssemblyModel assembly1 = new SolutionViewModel.AssemblyModel("MyAsBsembly");
            model.Assemblies.Add(assembly1);
            SolutionViewModel.ClassModel classModel = new SolutionViewModel.ClassModel("Class1");
            assembly1.Classes.Add(classModel);

            SolutionViewController controller =
               new SolutionViewController(new CommandFactory(), new CommandRunner(), model);

            //---------------Assert PreConditions---------------   
            Assert.IsNull(assembly1.CurrentClass);

            //---------------Execute Test ----------------------
            controller.SelectClass(assembly1, classModel);
            //---------------Test Result -----------------------
            Assert.AreSame(classModel, assembly1.CurrentClass);

            //---------------Tear Down -------------------------          
        }

        //Create class (using current assembly)
        [Test]
        public void Test_CreateClass()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = TestUtilsShared.CreateSavedDMSolution();
            SolutionViewModel solutionViewModel1 = SolutionViewModel.BuildFrom(dmSolution);
            string className = TestUtilsShared.GetRandomString();

            MockRepository mock = new MockRepository();
            ICommand command = MockRepository.GenerateStub<ICommand>();
            ICommandFactory commandFactory = MockRepository.GenerateStub<ICommandFactory>();
            ICommandRunner commandRunner = MockRepository.GenerateStub<ICommandRunner>();
            
            SolutionViewController controller =
                new SolutionViewController(commandFactory, commandRunner, solutionViewModel1);

            //--------------Set up expectations-----------------
            commandFactory.Expect(factory => commandFactory.CreateCreateClass(dmSolution.DefaultAssembly, className)).Return(command);
            commandRunner.Expect(runner => runner.ApplyCommand(command));
            mock.ReplayAll();

            //---------------Execute Test ----------------------
            controller.CreateClass(solutionViewModel1.CurrentAssembly, className);

            //---------------Test Result -----------------------
            mock.VerifyAll();
        }

        //delete class
        [Test]
        public void Test_DeleteClass()
        {
            //---------------Set up test pack-------------------
            DMSolution solution = TestUtilsShared.CreateSavedDMSolution();
            DMClass dmClass = solution.DefaultAssembly.CreateClass("Class1");
            dmClass.Save();

            SolutionViewModel solutionViewModel1 = SolutionViewModel.BuildFrom(solution);
            SolutionViewModel.ClassModel classModel = solutionViewModel1.Assemblies[0].Classes[0];

            MockRepository mock = new MockRepository();
            ICommand command = MockRepository.GenerateStub<ICommand>();
            ICommandFactory commandFactory = MockRepository.GenerateStub<ICommandFactory>();
            ICommandRunner commandRunner = MockRepository.GenerateStub<ICommandRunner>();

            ISolutionViewController controller =
                new SolutionViewController(commandFactory, commandRunner, solutionViewModel1);

            //--------------Set up expectations-----------------
            commandFactory.Expect(factory => commandFactory.CreateDeleteClass(dmClass)).Return(command);
            commandRunner.Expect(runner => runner.ApplyCommand(command));
            mock.ReplayAll();

            //---------------Execute Test ----------------------
            controller.DeleteClass(classModel);

            //---------------Test Result -----------------------
            mock.VerifyAll();
        }

        //Change class name
        [Test]
        public void Test_RenameClass()
        {
            //---------------Set up test pack-------------------
            DMSolution solution = TestUtilsShared.CreateSavedDMSolution();
            DMClass dmClass = solution.DefaultAssembly.CreateClass("Class1");
            dmClass.Save();

            SolutionViewModel solutionViewModel1 = SolutionViewModel.BuildFrom(solution);
            SolutionViewModel.ClassModel classModel = solutionViewModel1.Assemblies[0].Classes[0];

            MockRepository mock = new MockRepository();
            ICommand command = MockRepository.GenerateStub<ICommand>();
            ICommandFactory commandFactory = MockRepository.GenerateStub<ICommandFactory>();
            ICommandRunner commandRunner = MockRepository.GenerateStub<ICommandRunner>();

            ISolutionViewController controller =
                new SolutionViewController(commandFactory, commandRunner, solutionViewModel1);

            //--------------Set up expectations-----------------
            const string newname = "NewName";
            commandFactory.Expect(factory => commandFactory.CreateRenameClass(dmClass, newname)).Return(command);
            commandRunner.Expect(runner => runner.ApplyCommand(command));
            mock.ReplayAll();

            //---------------Execute Test ----------------------
            controller.RenameClass(classModel, newname);

            //---------------Test Result -----------------------
            mock.VerifyAll();  
        }




    }
}